// Copyright (c) Appeon. All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. 
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.

using System.Data;
using System.Threading;
using System.Threading.Tasks;

namespace SnapObjects.Data
{
    internal class SqlUpdateCommand : UpdateCommand
    {
        public SqlUpdateCommand(DataContext dataContext)
            : base(dataContext)
        {
        }

        public void Execute(IUpdatableSql updatableSql)
        {
            this.InitCommand();

            _dataContext.CurrentConnection.Open();
            IAdoDbDataVisitor result = null;

            try
            {
                var commandBuilder = new SqlCommandBuilder(_dataContext);
                commandBuilder.BuildCommand(updatableSql);

                this.BuiltSql = _dataContext.AdoDbSqlProvider.SqlGenerationHelper.SqlBegin
                    + commandBuilder.BuiltSql
                    + _dataContext.AdoDbSqlProvider.SqlGenerationHelper.SqlEnd;

                result = _adoDbProvider.ExecuteSqlQuery(this.BuiltSql, commandBuilder.GetAdoDbParameters());

                this.ConsumeResult(updatableSql, ResultSetMapping.RowCountAndLastInResultSet, result);
            }
            finally
            {
                result?.Dispose();
                _dataContext?.CurrentConnection?.Close();
            }
        }

        public async Task ExecuteAsync(IUpdatableSql updatableSql, CancellationToken cancellationToken)
        {
            this.InitCommand();

            await _dataContext.CurrentConnection.OpenAsync(cancellationToken);

            IAdoDbDataVisitor result = null;

            try
            {
                var commandBuilder = new SqlCommandBuilder(_dataContext);
                commandBuilder.BuildCommand(updatableSql);

                this.BuiltSql = _dataContext.AdoDbSqlProvider.SqlGenerationHelper.SqlBegin
                    + commandBuilder.BuiltSql
                    + _dataContext.AdoDbSqlProvider.SqlGenerationHelper.SqlEnd;

                result = await _adoDbProvider.ExecuteSqlQueryAsync(
                    this.BuiltSql, commandBuilder.GetAdoDbParameters(), cancellationToken);

                this.ConsumeResult(updatableSql, ResultSetMapping.RowCountAndLastInResultSet, result);
            }
            finally
            {
                if (result != null)
                {
                    await result.DisposeAsync();
                }

                await _dataContext?.CurrentConnection?.CloseAsync();
            }
        }
    }
}
